﻿#include "qcpuinfoprovider.h"
#include <QProcess>
#include <QStringList>
#include <QDebug>

QCpuInfoProvider::QCpuInfoProvider(QObject *parent)
    : QObject(parent)
{
}

QList<QCpuInfoProvider::CpuDetails> QCpuInfoProvider::getAllCpusDetails() const {
#ifdef Q_OS_WIN
    return getCpusDetailsWindows();
#elif defined(Q_OS_LINUX)
    return getCpusDetailsLinux();
#else
    return {};
#endif
}

QList<QCpuInfoProvider::CpuDetails> QCpuInfoProvider::getCpusDetailsWindows() const {
    QList<CpuDetails> cpuDetailsList;
    QProcess process;

    // Use WMI to get detailed information about each CPU.
    process.start("wmic", QStringList() << "cpu" << "get" << "/format:list");
    process.waitForFinished();
    QString cpuInfo = process.readAllStandardOutput();

    QStringList cpuBlocks = cpuInfo.split("\r\r\n\r\r\n", Qt::SkipEmptyParts);
    foreach (const QString &block, cpuBlocks) {
        CpuDetails details;
        details.model = extractValueFromWmic(block, "\nName=");
        details.vendor = extractValueFromWmic(block, "\nManufacturer=");
        details.architecture = extractValueFromWmic(block, "\nAddressWidth=").contains("64") ? "x86_64" : "x86";
        details.cacheSize = extractValueFromWmic(block, "\nL3CacheSize=") + " KBytes";
        details.maxFrequency = extractValueFromWmic(block, "\nMaxClockSpeed=") + " MHz";
        details.physicalCores = extractValueFromWmic(block, "\nNumberOfCores=").toInt();
        details.logicalCores = extractValueFromWmic(block, "\nNumberOfLogicalProcessors=").toInt();
        details.minFrequency = extractValueFromWmic(cpuInfo, "\nCurrentClockSpeed=") + " MHz";

        cpuDetailsList.append(details);
    }

    return cpuDetailsList;
}

QList<QCpuInfoProvider::CpuDetails> QCpuInfoProvider::getCpusDetailsLinux() const {
    QList<CpuDetails> cpuDetailsList;
    QProcess process;
    process.start("lscpu");
    process.waitForFinished();
    QString lscpuOutput = process.readAllStandardOutput();
    QStringList lines = lscpuOutput.split('\n');

    CpuDetails details;
    bool newCpu = true;

    foreach (const QString &line, lines) {
        if (line.contains("Socket(s)")) {
            // If there are multiple sockets, we should handle them here.
            // This is a simplified approach and may need adjustments for multi-socket systems.
            continue;
        } else if (line.contains("Model name")) {
            if (!newCpu && !details.model.isEmpty()) {
                cpuDetailsList.append(details);
                details = {}; // Reset details for the next CPU.
            }
            details.model = line.split(":").at(1).simplified();
            newCpu = false;
        } else if (line.contains("Vendor ID")) {
            details.vendor = line.split(":").at(1).simplified();
        } else if (line.contains("Architecture")) {
            details.architecture = line.split(":").at(1).simplified();
        } else if (line.contains("Core(s) per socket")) {
            details.physicalCores = line.split(":").at(1).simplified().toInt();
        } else if (line.contains("CPU(s)")) {
            details.logicalCores = line.split(":").at(1).simplified().toInt();
        } else if (line.contains("L3 cache")) {
            details.cacheSize = line.split(":").at(1).simplified();
        } else if (line.contains("CPU MHz")) {
            details.maxFrequency = line.split(":").at(1).simplified(); // Note: This might not be the max frequency, adjust as needed.
        } else if (line.contains("CPU min MHz")) {
            details.minFrequency = line.split(":").at(1).simplified();
        }
    }

    if (!details.model.isEmpty()) {
        cpuDetailsList.append(details);
    }

    return cpuDetailsList;
}

QString QCpuInfoProvider::extractValueFromWmic(const QString& input, const QString& key) const {
    return input.section(key, 1, 1).section('\n', 0, 0).simplified();
}
